home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
ab20
/
ab20_archive
/
utilities
/
shells
/
csh519s.lha
/
comm3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-24
|
33KB
|
1,731 lines
/*
* COMM3.C
*
* Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
* Version 5.00L by Urban Mueller 17-Feb-91
*
*/
#include "shell.h"
/* comm3.c */
static void doassign(char *log, char *phy);
static void assignlist(void);
static int strings_in_file(long mask, char *s, char *path);
static int htype_a_file (long mask, char *s, char *path);
static void install_menu(char **mav, int mac);
static int line_filter( char *(*line)(char *) );
do_tee( void )
{
char buf[256];
FILE *out;
prepscroll( ac==1 );
if( ac>2 ) { ierror( av[2], 500 ); return 20; }
if( ac==1 ) out=stderr;
else if( !(out=fopen( av[1], "w" ))) { pError( av[1] ); return 20; }
while (safegets(buf,stdin)) {
puts(buf);
quickscroll();
fprintf(out,"%s\n",buf);
}
if( ac!=1 ) fclose( out );
return 0;
}
do_head( char *garbage, int com )
{
int i, n;
FILE *f;
char buf[256];
if (ac>2) {
n=(int)(long)Atol(av[2]);
if (IoErr()) {
ierror(av[2],511);
return 20;
}
} else n=10;
f=fopen(av[1], "r");
if (f==NULL) {
pError(av[1]);
return 20;
}
if (com) { /* tail specific part */
i=0;
while (fgets(buf, 256, f) && ! dobreak()) i++;
rewind(f);
if (n>i) n=i;
i=i-n;
while (i-- && fgets(buf, 256, f) && ! dobreak()) ;
}
for (i=1; i<=n && fgets(buf, 256, f) && ! dobreak(); i++)
printf("%s", buf);
fclose(f);
return 0;
}
static int
exword( char **src, char *buf )
{
*buf=0;
if( **src==0 ) return 0;
while( **src && **src!=0xA0 )
*buf++=*(*src)++;
*buf=0;
if( **src ) (*src)++;
return 1;
}
static char helpfound=0;
void
man (FILE *f, char *s)
{
char buf[140], entry[100];
int len = sprintf (entry, " %s", s);
char *example = " ";
prepscroll (0);
rewind (f);
do { /* look for required argument */
if (fgets (buf, sizeof(buf), f)==NULL || dobreak())
return; /* GMD */
} while (Strncmp (entry, buf, len)) ;
helpfound = 1;
do { /* display help */
if (dobreak())
return;
quickscroll ();
printf ("%s", buf);
if (fgets (buf, sizeof(buf), f) == NULL)
return;
} while ((!isalphanum (*buf)) && strncmp (buf, example, strlen(example))) ;
}
do_man( void )
{
FILE *f;
int i;
char buf[200], name[60], *src, *var, docfound=0;
buf[0]=0;
if( var=get_var(LEVEL_SET,"_man" ) )
strcpy(buf,var);
if (ac==1) ac=2, av[1]="MAN";
for (i=1; i<ac; i++) {
src=buf, helpfound=0;
while( exword( &src, name) )
if( f=fopen(name, "r") ) {
docfound=1;
man(f, av[i]);
fclose(f);
if( helpfound )
break;
}
if( !docfound )
fprintf(stderr,"%s not found\n",buf);
else if( !helpfound )
fprintf(stderr, "Help not found for %s\n", av[i]);
}
return 0;
}
do_assign( void )
{
int i;
if ( ac==1 ) assignlist();
else if( ac==2 ) doassign(av[1], NULL);
else if( !(ac&1) ) ierror(NULL, 500);
else
for( i=1; i<ac; i+=2 )
doassign( av[i],av[i+1] );
return 0;
}
static char *assign_errors[4]={
"",
"Name %s is not valid\n",
"Weird error\n",
"Can't cancel %s:\n"
};
static void
doassign(char *log, char *phy)
{
int last=strlen(log) - 1;
if (log[last] != ':') fprintf(stderr, "Bad name %s\n", log);
else {
log[last] = 0;
#ifdef KICK20
if( options && phy && o_kick20 ) {
BPTR lock;
int succ=0;
if ( options&1 ) succ=AssignLate( (UBYTE*)log,(UBYTE*)phy );
else if( options&2 ) succ=AssignPath( (UBYTE*)log,(UBYTE*)phy );
else if( options&4 )
if( lock=Lock(phy,ACCESS_READ) )
if( !(succ=AssignAdd((UBYTE *)log,lock)))
UnLock(lock);
if( !succ )
pError( log );
} else
#endif
if( !(options&4) ) {
int err=Assign(log, phy);
fprintf(stderr,assign_errors[err],err==1?phy:log);
}
}
}
extern struct RootNode2x *RootNode;
#define ENTRIES 128
static void
assignlist()
{
char *ptr, *log, **arr;
int ctr, i;
if(!(arr=expand_devs()))
return;
printf("Devices:\n");
for (i=ctr=0; arr[i] && *arr[i]==1; i++) {
printf("%-8s",arr[i]+1);
if (ctr++ == 5) { ctr=0; printf("\n"); }
}
printf("\n\nVolumes:\n");
for( ; arr[i] && *arr[i]==2; i++ )
printf( "%-16s [Mounted]\n",arr[i]+1);
printf("\nDirectories:\n");
for( ; arr[i] && !dobreak(); i++ ) {
log=arr[i]+1; ptr=log+strlen(log)+1;
switch( *(log-1)) {
case 3:
printf("%-20s%s\n", log, ptr);
for(;;) {
ptr+=strlen(ptr)+1;
if( !*ptr ) break;
printf("%-19s+%s\n", "", ptr);
}
break;
case 4: printf("%-20s<%s>\n", log, ptr); break;
case 5: printf("%-20s[%s]\n", log, ptr); break;
}
}
free_expand( arr );
}
char **
expand_devs(void)
{
static char Type[]={1,3,2,4,5};
struct DosInfo *info=(void*)((long)RootNode->rn_Info*4);
struct DosList2x *list=(void*)((long) info->di_DevInfo*4);
struct AssignList2x *path;
char buf[256], **arr, *ptr;
int n;
if( !(arr=malloc(ENTRIES*sizeof(char *))))
return NULL;
Forbid();
for( n=0; list && n<ENTRIES; list=(void*)((long)list->dol_Next*4)) {
if( list->dol_Type<0 || list->dol_Type>DLST_NONBINDING )
continue;
ptr=buf;
*ptr++=Type[list->dol_Type];
ptr+=BtoCStr(ptr,list->dol_Name,200);
*ptr++=':'; *ptr++=0;
switch( list->dol_Type) {
case DLST_DIRECTORY :
if(list->dol_Lock)
PathName(list->dol_Lock, ptr, 200);
else
strcpy(ptr,"Nonexisting lock");
ptr+=strlen(ptr)+1;
if( o_kick20 ) {
path=(void*)list->dol_misc.dol_assign.dol_List;
for( ; o_kick20 && path; path=(void*)path->al_Next ) {
if(list->dol_Lock)
PathName(path->al_Lock, ptr, 200);
else
strcpy(ptr,"Nonexisting lock");
ptr+=strlen(ptr)+1;
}
}
*ptr++=0;
break;
case DLST_LATE :
case DLST_NONBINDING:
ptr+= sprintf(ptr,"%s",list->dol_misc.dol_assign.dol_AssignName);
*ptr++=0;
break;
default:
*ptr++=0;
}
arr[n]=salloc(ptr+1-buf);
memcpy(arr[n++],buf,ptr+1-buf);
}
arr[n]=NULL;
Permit();
QuickSort( arr, n );
return arr;
}
do_join( void )
{
BPTR sou, dest;
char *buffer;
int i;
long n;
char *namedest=av[--ac];
if (options==0 && exists(namedest)) { ierror(namedest,203); return 20; }
if ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; }
if ( (dest=Open(namedest, MODE_NEWFILE)) == NULL )
{ pError(namedest); goto fail1; }
for (i=1; i<ac; i++) {
if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]);
else
while( (n=Read(sou, buffer, 8192L)) > 0 )
if (Write(dest, buffer, n) != n)
{ pError(namedest); Close(sou); goto fail2; }
Close(sou);
}
fail2:
Close(dest);
fail1:
free(buffer);
return 0;
}
#define BUFDIM 512L
#define MAXSTR 256
int minstr;
static int
strings_in_file(long mask, char *s, char *path)
{
char c;
char readbuf[BUFDIM+1], strbuf[MAXSTR+1];
int i, strctr=0;
BPTR fh;
int out, n, inter=IsInteractive(Output());;
prepscroll(0);
if ( fh=Open(s, MODE_OLDFILE) ) {
fprintf(stdout, "Strings in %s (len>=%d):\n",path,minstr);
while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() )
for (i=0; i<n; i++) {
c=readbuf[i];
if (c<0x20 || c>0x7f) {
out=(strctr>=minstr);
if (!out) strctr=0;
} else {
strbuf[strctr++]=c;
out=(strctr>=BUFDIM);
}
if (out) {
strbuf[strctr]='\0';
puts(strbuf);
if( inter ) fflush(stdout);
quickscroll();
strctr=0;
}
}
Close(fh);
} else
pError(s);
return 0;
}
do_strings( void )
{
minstr=myatoi(av[--ac],1,255);
all_args( strings_in_file, 0);
return 0;
}
BPTR myfile[MAXMYFILES];
do_open( void )
{
long mode;
int n;
switch (toupper(av[2][0])) {
case 'R': mode=MODE_OLDFILE; break;
case 'W': mode=MODE_NEWFILE; break;
default : ierror(NULL,500); return 1;
}
n=myatoi(av[3],0,MAXMYFILES-1); if (atoierr) return 20;
if (myfile[n]) myclose(n);
myfile[n]=Open(av[1],mode);
return myfile[n]==NULL;
}
do_close( void )
{
int i, n;
if (ac==1)
for (i=1; i<MAXMYFILES; i++)
myclose(i);
for (i=1; i<ac; i++) {
n=myatoi(av[i],0,MAXMYFILES-1); if (atoierr) return 20;
myclose(n);
}
return 0;
}
void
myclose(int n)
{
if (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; }
}
do_fileslist( void )
{
int i, flag=0;
printf("Open files:");
for (i=0; i<MAXMYFILES; i++)
if (myfile[i]) { printf(" %d",i); flag=1; }
if (!flag) printf(" None!");
printf("\n");
return 0;
}
BPTR
extOpen( char *name, long mode )
{
if (name[0]=='.' && name[1]>='0' && name[1]<='9')
return myfile[atoi(name+1)];
return Open(name,mode);
}
void
extClose(BPTR fh)
{
int i;
for (i=0; i<MAXMYFILES; i++)
if (myfile[i]==fh) return;
Close(fh);
}
do_basename( void )
{
char *res;
int i;
for( i=2; i<ac; i++ )
av[i]=BaseName(av[i]);
set_var(LEVEL_SET, av[1], res=compile_av(av,2,ac,0xA0,0));
free(res);
return 0;
}
do_tackon( void )
{
char buf[256];
strcpy(buf, av[2]);
TackOn(buf, av[3]);
set_var(LEVEL_SET, av[1], buf);
return 0;
}
extern char shellres[];
do_resident( void )
{
int i=1;
struct ResidentProgramNode *p;
char buf[256];
if (options==0 && ac>1) options=1;
switch (options) {
case 0:
ObtainSemaphore (& (ArpBase->ResPrgProtection) );
if (p=ArpBase->ResidentPrgList) {
printf("Name Users Access\n");
for (; p; p=p->rpn_Next)
printf("%-17s%5d%6d\n",
p->rpn_Name, p->rpn_Usage, p->rpn_AccessCnt);
} else
printf("No resident program(s)\n");
ReleaseSemaphore(& (ArpBase->ResPrgProtection) );
break;
case 1:
for (; i<ac; i++)
if (loadres(av[i]))
printf("OK! %s is now resident\n", BaseName(av[i]));
else
pError(av[i]);
break;
case 2:
for (; i<ac; i++)
if (RemResidentPrg(av[i])) ierror(av[i],202);
else printf("Removed %s\n",av[i]);
break;
case 4:
for (; i<ac; i++) {
if( !o_resident ) {
Setenv(shellres,"1");
o_resident=1;
}
sprintf(buf,"res_%s",BaseName(av[i]));
Setenv(buf,av[i]);
}
break;
default:
ierror(NULL,500);
break;
}
return 0;
}
int
loadres(char *s)
{
BPTR seg;
if (seg=(BPTR)LoadPrg(s)) AddResidentPrg(seg,BaseName(s));
return (seg != NULL);
}
static struct ProcessControlBlock pcb={
4000, /* pcb_StackSize */
0, /* pcb_Pri */
};
/* remaining fields are NULL */
extern BPTR redir_out, redir_in;
struct TagItem tags[]={
{SYS_Input, 0},
{SYS_Output, 0},
{SYS_Asynch, 1},
{TAG_DONE, 0} };
do_truerun(char *avline, int backflag)
{
BPTR input, output;
char name[100], *args, buf[10], *console=o_kick20 ? "CONSOLE:" : "*";
int cli, err;
if (backflag) {
input = Open("NIL:",MODE_NEWFILE);
output= Open("NIL:",MODE_NEWFILE);
} else {
input = redir_in ?redir_in : Open("NIL:" , MODE_NEWFILE);
output= redir_out?redir_out: Open(console, MODE_NEWFILE);
}
if( o_kick20 ) {
args=compile_av(av,1,ac,' ',1);
tags[0].ti_Data= input;
tags[1].ti_Data= output;
err=System( args, tags );
if( err!=0 ) {
Close( tags[0].ti_Data );
Close( tags[1].ti_Data );
pError(av[1]);
}
free(args);
} else {
args=next_word(next_word(avline));
pcb.pcb_Control= NULL;
pcb.pcb_Input = input;
pcb.pcb_Output = output;
if((cli=ASyncRun(av[1],args,&pcb))<0)
if (dofind(av[1], "", name,v_path))
cli=ASyncRun(name,args,&pcb);
sprintf(buf,"%d",cli);
set_var(LEVEL_SET,"_newproc",buf);
}
if( cli<0 ) {
pError(av[1]);
return 20;
}
return 0;
}
#if 0
extern BPTR redir_out, redir_in;
do_truerun(char *avline, int backflag)
{
char name[100], *args, buf[10];
int cli;
args=next_word(next_word(avline));
if (backflag) {
pcb.pcb_Control= 0;
pcb.pcb_Input = Open("NIL:",MODE_OLDFILE);
pcb.pcb_Output = Open("NIL:",MODE_OLDFILE);
} else {
pcb.pcb_Control= 0;
pcb.pcb_Input = redir_in;
pcb.pcb_Output = redir_out;
}
if((cli=ASyncRun(av[1],args,&pcb))<0)
if (dofind(av[1], "", name,v_path))
cli=ASyncRun(name,args,&pcb);
if( cli<0 && cli>=-11 ) {
if( redir_out ) extClose( redir_out );
if( redir_in ) extClose( redir_in );
}
sprintf(buf,"%d",cli);
set_var(LEVEL_SET,"_newproc",buf);
if( cli<0 ) {
ierror(av[1],205);
return 20;
}
return 0;
}
#endif
int
exists( char *name )
{
BPTR lock;
char *nam=BaseName(name);
int ret=0;
Myprocess->pr_WindowPtr = (APTR)(-1);
if ( strlen(nam)<=MAXFILENAME && (lock=Lock(name,ACCESS_READ))) {
UnLock(lock);
ret=1;
}
Myprocess->pr_WindowPtr = (APTR) o_noreq;
return ret;
}
int
mounted( char *dev )
{
char *str, **get=expand_devs();
while( (str=*get++) && Strcmp(str+1,dev) ) ;
free_expand(get);
return (int)str;
}
do_aset( void )
{
Setenv(av[1],av[2]);
return 0;
}
#define HTYPELINE 16L
static int
htype_a_file(long mask, char *s, char *path)
{
BPTR fh;
long n, filesize=0;
UBYTE buf[HTYPELINE+1];
char out[80], *put;
int i, inter=IsInteractive(Output());
if ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; }
prepscroll(0);
while ( (n=Read(fh,(char *)buf,HTYPELINE))>0 && !dobreak()) {
put=out;
put+=sprintf(put,"%06lx: ",filesize);
filesize+=n;
for (i=0; i<n; i++) {
put+=sprintf( put,(i&3) ? "%02x" : " %02x",buf[i]);
if ((buf[i]&127)<0x20) buf[i]='.';
}
for ( ; i<HTYPELINE; i++) {
put+=sprintf( put, (i&3) ? " " : " ");
buf[i]=' ';
}
buf[i]=0;
sprintf(put," %s",buf);
puts(out);
if( inter ) fflush(stdout);
quickscroll();
}
Close(fh);
return 0;
}
do_htype( void )
{
all_args( htype_a_file, 0);
return 0;
}
do_stack( void )
{
long n;
if (ac>1) {
n=Atol(av[1]);
if (!IoErr()) Mycli->cli_DefaultStack=(long)(n >> 2L);
}
else printf("current stack size is %ld bytes\n",
(long)Mycli->cli_DefaultStack << 2L);
return 0;
}
do_fault( void )
{
PERROR *p;
int i, n;
for (i=1; i<ac; i++) {
n=myatoi(av[i],0,32767);
if (!atoierr) {
for (p=Perror; p->errnum && p->errnum!=n; p++);
if (p->errnum)
printf("Fault %d: %s\n",n,p->errstr);
else
printf("Fault %d not recognized\n",n);
}
}
return 0;
}
struct rpncommand {
char *str;
int parsin, parsout;
};
static struct rpncommand rpn[]={
"+", 2, 1,
"-", 2, 1,
"*", 2, 1,
"/", 2, 1,
"%", 2, 1,
"&", 2, 1,
"|", 2, 1,
"~", 1, 1,
">", 2, 1,
"<", 2, 1,
"==", 2, 1,
"!", 1, 1,
"MAX", 2, 1,
"MIN", 2, 1,
"DUP", 1, 2,
"DROP", 1, 0,
"SWAP", 2, 2,
"HELP", 0, 0,
NULL, 0, 1, /* this looks for a number */
};
static long stack[50];
static int sp;
eval_rpn( char **av, int ac, int flag )
{
char *zero="Division by zero\n";
struct rpncommand *temp;
long n0, n1, t;
int j, i=0, oldsp=sp;
for (; i<ac; i++) {
for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ;
n0=stack[sp-1];
n1=stack[sp-2];
sp -= (rpn[j].parsin);
if (sp<0) { fprintf(stderr, "RPN: Empty stack\n"); goto error; }
switch (j) {
case 0: n0 += n1; break;
case 1: n0 = n1-n0; break;
case 2: n0 *= n1; break;
case 3: if(n0) n0=n1/n0; else fprintf(stderr,zero); break;
case 4: if(n0) n0=n1%n0; else fprintf(stderr,zero); break;
case 5: n0 &= n1; break;
case 6: n0 |= n1; break;
case 7: n0 = ~n0 ; break;
case 8: n0 = (n1 > n0); break;
case 9: n0 = (n1 < n0); break;
case 10: n0 = (n0 == n1); break;
case 11: n0 = !n0; break;
case 12: n0=n1>n0 ? n1 : n0; break;
case 13: n0=n1<n0 ? n1 : n0; break;
case 14: n1=n0; break;
case 15: t=n0; n0=n1; n1=t; break;
case 16: break;
case 17: printf("In Commands Out\n");
for (temp=rpn; temp->str; temp++)
printf(" %d %-10s%d\n",
temp->parsin,temp->str,temp->parsout);
break;
default: n0=Atol(av[i]);
if (IoErr()) {
fprintf(stderr, "Bad RPN cmd: %s\n",av[i]);
goto error;
}
break;
}
stack[sp]=n0;
stack[sp+1]=n1;
sp += rpn[j].parsout;
}
if( flag && sp-1)
fprintf(
stderr,
"RPN: Stack not empty\n"
);
t=sp; sp=oldsp;
if( flag )
return stack[t-1]; /* return top value */
else
return t-sp;
error:
sp=oldsp;
return 0;
}
do_rpn(char *garbage,int ifflag) /* ifflag!=0 if called from if */
{
int i=1;
long t;
t=eval_rpn( av+i, ac-i, ifflag );
if (ifflag) return t; /* called from if: return top value */
for (i=sp+t-1;i>=sp;i--) printf("%ld\n", stack[i]);/* else print stack */
return t ? 0 : 20;
}
do_path( void )
{
ULONG ll, ll1, *lp, new, *newp;
char buf[256];
BPTR lock;
int i;
if( options&1 ) {
Forbid();
for( ll= Mycli->cli_CommandDir; ll; ll= ll1 ) {
lp=(ULONG *)(4*ll);
ll1=lp[0];
UnLock(lp[1]);
DosFreeMem( lp );
}
Mycli->cli_CommandDir=0;
Permit();
} else if( ac==1 ) { /* Should Forbid() here, but puts() Permit()s */
puts("Current dir"); /* and failure here is not really harmful... */
for( ll= Mycli->cli_CommandDir; ll; ll= *lp ) {
lp=(ULONG *)(4*ll);
PathName(lp[1], buf, 256L);
puts(buf);
}
puts("C:");
return 0;
}
for( i=1; i<ac; i++ ) {
if( !(lock=Lock(av[i],ACCESS_READ)) ) {
ierror(av[i],205);
continue;
}
if( !isdir(av[i])) {
ierror(av[i],212);
UnLock(lock);
continue;
}
Forbid();
for( ll= Mycli->cli_CommandDir, lp=NULL; ll; ll= lp[0] ) {
lp=(ULONG *)(4*ll);
if( CompareLock(lp[1],lock)==LCK_EQUAL) {
UnLock(lock), lock=0;
break;
}
}
if( lock && (newp=DosAllocMem( 8 ))) {
newp[1]=lock;
new =(ULONG)newp/4;
if( lp )
*lp=new;
else
Mycli->cli_CommandDir=new;
}
Permit();
}
return 0;
}
do_pri( void )
{
int t, pri;
struct Process *proc;
t=(int)(long)FindCLI(0L);
t=myatoi(av[1],0,t); if (atoierr) return 20;
pri=myatoi(av[2],-128,127); if (atoierr) return 20;
Forbid();
proc=(t==0 ? Myprocess : FindCLI((long)t));
if (proc==NULL) fprintf(stderr, "process not found\n");
else SetTaskPri((struct Task *)proc, (long)pri);
Permit();
return 0;
}
do_strleft( void )
{
int n;
n=posatoi(av[3]); if (atoierr) return 20;
set_var_n(LEVEL_SET, av[1], av[2], n);
return 0;
}
do_strright( void )
{
int n, len=strlen(av[2]);
n=posatoi(av[3]); if (atoierr) return 20;
if( n>len ) n=len;
set_var(LEVEL_SET, av[1], av[2]+len-n );
return 0;
}
do_strmid( void )
{
int n1, n2=999999, len=strlen(av[2]);
n1=myatoi(av[3],1,999999)-1; if (atoierr) return 20;
if (n1>len) n1=len;
if (ac>4) {
n2=posatoi(av[4]); if (atoierr) return 20;
}
set_var_n(LEVEL_SET, av[1], av[2]+n1, n2);
return 0;
}
do_strlen( void )
{
char buf[16];
sprintf(buf,"%d",strlen(av[2]));
set_var(LEVEL_SET, av[1], buf);
return 0;
}
int atoierr;
myatoi(char *s,int mmin,int mmax)
{
int n;
n=Atol(s);
if (atoierr=IoErr())
ierror(s,511);
else if (n<mmin || n>mmax) {
atoierr=1; n=mmin;
fprintf( stderr, "%s(%d) not in (%d,%d)\n",s,n,mmin,mmax );
}
return n;
}
unlatoi(char *s)
{
int n=Atol(s);
if (atoierr=IoErr())
ierror(s,511), n=0;
return n;
}
posatoi(char *s)
{
int n=Atol(s);
if (atoierr=IoErr())
ierror(s,511);
else if (n<0 )
atoierr=1, n=0, fprintf( stderr, "%s must be positive\n",s );
return n;
}
do_fltlower( void )
{
return line_filter( strlwr );
}
do_fltupper( void )
{
return line_filter( strupr );
}
#if 0
char *
stripcr( char *get )
{
char *old=get, *put;
for( put=get; *get; get++ )
if( *get!=13 )
*put++=*get;
*put++=0;
return old;
}
do_fltstripcr( void )
{
return line_filter( stripcr );
}
#endif
static int
line_filter( char *(*func)( char * ) )
{
char buf[256];
while (!CHECKBREAK() && myfgets(buf,stdin))
puts((*func)(buf));
return 0;
}
int
do_linecnt( void )
{
int count=0;
char buf[256];
while (!CHECKBREAK() && fgets(buf,255,stdin)) ++count;
printf("%d lines\n",count);
return 0;
}
int
do_uniq( void )
{
int firstline=1;
char buf[256], oldbuf[256];
while (!CHECKBREAK() && myfgets(buf,stdin)) {
if ( firstline || strcmp(buf, oldbuf)) {
strcpy(oldbuf, buf);
puts(buf);
}
firstline=0;
}
return 0;
}
#define RXFB_RESULT 17
#define RXCOMM 0x01000000
static struct rexxmsg {
struct Message rm_Node; /* EXEC message structure */
APTR rm_TaskBlock; /* global structure (private) */
APTR rm_LibBase; /* library base (private) */
LONG rm_Action; /* command (action) code */
LONG rm_Result1; /* primary result (return code) */
LONG rm_Result2; /* secondary result */
STRPTR rm_Args[16]; /* argument block (ARG0-ARG15) */
struct MsgPort *rm_PassPort; /* forwarding port */
STRPTR rm_CommAddr; /* host address (port name) */
STRPTR rm_FileExt; /* file extension */
LONG rm_Stdin; /* input stream (filehandle) */
LONG rm_Stdout; /* output stream (filehandle) */
LONG rm_avail; /* future expansion */
} mymsg; /* size: 128 bytes */
do_rxsend( char *avline )
{
int i, ret=0;
long result;
struct MsgPort *port, *reply;
long len;
char buf[20], *resptr;
if (!(port = (struct MsgPort *)FindPort(av[1])))
{ fprintf(stderr, "No port %s!\n", av[1]); return 20; }
mymsg.rm_Node.mn_Node.ln_Type = NT_MESSAGE;
mymsg.rm_Node.mn_Length = sizeof(struct rexxmsg);
mymsg.rm_Action = RXCOMM | (options&1 ? 1L << RXFB_RESULT : 0);
if (!(reply = CreatePort(NULL, 0L))) {
fprintf(stderr, "No reply port\n");
return 20;
}
mymsg.rm_Node.mn_ReplyPort = reply;
if( options&2 )
av[2]=compile_av( av,2,ac,' ',0), ac=3;
for ( i=2; i<ac; i++) {
mymsg.rm_Args[0] = av[i];
mymsg.rm_Result2 = 0; /* clear out the last result. */
PutMsg(port, &mymsg.rm_Node);
Wait( 1<<reply->mp_SigBit | SIGBREAKF_CTRL_C );
if( CHECKBREAK() ) {
ret=5;
break;
}
if (options&1) {
if( (result=mymsg.rm_Result2)<1000000 ) { /* like AREXX */
sprintf(buf,"%d",result);
set_var(LEVEL_SET,v_result,buf);
} else {
resptr=(char *)(result-4);
len=*(long *)resptr;
memmove(resptr,resptr+4,len); /* Null terminate */
resptr[len]=0;
set_var(LEVEL_SET,v_result,resptr);
FreeMem(resptr, len+4 );
}
} else
unset_var( LEVEL_SET, v_result );
}
if( options&2 )
free( av[2] );
if (reply) DeletePort(reply);
return ret;
}
static char *rxreturn;
do_rxrec( void )
{
struct MsgPort *port;
struct rexxmsg *msg;
char *portname, *str;
if (ac > 1)
portname=av[1];
else
portname="rexx_csh";
port=CreatePort(portname, 0L);
if (port==NULL) {
fprintf(stderr, "Can't have MsgPort %s\n", portname);
return 20;
}
for (;;) {
WaitPort(port);
while (msg=(struct rexxmsg *)GetMsg(port)) {
if ( ! Strcmp(msg->rm_Args[0], "bye")) {
ReplyMsg((struct Message *)msg);
DeletePort(port);
return 0;
}
rxreturn=NULL;
exec_command(msg->rm_Args[0]);
if (msg->rm_Action & (1L << RXFB_RESULT)) {
if( rxreturn ) {
str= SAllocMem( strlen( rxreturn )+5 , 0 );
*(long *)str=strlen( rxreturn );
strcpy( str+4, rxreturn );
msg->rm_Result2=(long)str;
} else {
str = get_var(LEVEL_SET, v_lasterr);
msg->rm_Result2=(str) ? atoi(str) : 20;
}
}
ReplyMsg((struct Message *)msg);
}
}
}
int
do_waitport( void )
{
int count=4*10;
struct MsgPort *port=NULL;
if( ac==3 )
{ count=2*myatoi(av[2],0, 32000); if( atoierr ) return 20; }
while( --count>=0 && !(port=FindPort(av[1])) && !dobreak() )
Delay(12);
return port ? 0 : 20;
}
int
do_rxreturn( void )
{
rxreturn=compile_av( av, 1, ac, ' ', 1 );
return 0;
}
do_ascii( void )
{
int x=1, y, c, c1, t;
char *fmt1=" %3d %c%c |", *fmt2=" %4d";
if( options&1 ) fmt1=" %3o %c%c |", fmt2="%4o";
if( options&2 ) fmt1=" %3x %c%c |", fmt2="%4x";
if( ac==x )
for( y=0; y<32 && !dobreak(); y++ ) {
printf("|");
for( x=0; x<8; x++ ) {
c1=c=y+32*x; t=' ';
if( c<32 ) t='^', c1+=64;
printf(fmt1,c, t, c1<128 || c1>=160?c1:'.');
}
printf("\n");
}
else
for( ; x<ac && !dobreak(); x++ ) {
for( y=0; y<strlen(av[x]); y++ )
printf(fmt2,av[x][y]);
printf("\n");
}
return 0;
}
void
appendslash( char *path )
{
int c;
if( (c=path[strlen(path)-1]) !='/' && c!=':' )
strcat(path,"/");
}
static void
whereis( char *path, char *file )
{
char **eav, buf[100];
int eac, j;
buf[0]=0;
if( path ) {
strcpy(buf,path);
appendslash(buf);
}
strcat(buf,".../");
strcat(buf,file);
if( !index( file, '*' ) && !index( file, '?') )
strcat(buf,"*");
if(eav=expand(buf,&eac)) {
for( j=0; j<eac && !dobreak(); j++ )
printf("%s\n",eav[j]);
free_expand(eav);
}
}
do_whereis( void )
{
char buf[200], *prev, *devs;
int i;
if( index( av[1],':') || index( av[1],'/' ) )
{ fprintf(stderr,"No paths please\n"); return 20; };
if( options&1 ) {
Myprocess->pr_WindowPtr = (APTR)(-1);
get_drives( devs=buf );
do {
prev=devs; devs=index(devs,0xA0);
if( devs ) *devs++=0;
whereis( prev, av[1] );
} while( devs );
Myprocess->pr_WindowPtr = (APTR) o_noreq;
} else if( ac==2 ) {
whereis( NULL, av[1] );
} else {
for( i=2; i<ac; i++ ) {
strcpy(buf,av[i]);
appendslash( buf );
whereis( buf, av[1] );
}
}
return 0;
}
do_usage( void )
{
int i;
if( ac==1 ) {
printf("Usage: usage [command...command]\n");
printf("[ ]=option [ | ]=choice { }=repetition name...name=1 or more names\n");
} else
for( i=1; i<ac; i++ )
show_usage( av[i] );
return 0;
}
int NumMenus;
do_menu( void )
{
if( o_nowindow )
return 5;
if( options&1 )
remove_menu();
if( ac==2 )
show_usage( NULL );
else if( NumMenus<MAXMENUS && ac!=1)
install_menu( av+1, ac-1 );
set_menu();
return 0;
}
#define NUMITE 40
#define TITWID 90
#define ITEWID 148
static struct Menu DefaultMenu= {0, 0,0,TITWID,10, MENUENABLED,0,0};
static struct IntuiText DefaultIntuiText= {0,1,JAM2, 1,1,NULL,0,0};
static struct MenuItem DefaultMenuItem=
{0, 0,0,ITEWID,0, HIGHCOMP|ITEMTEXT|ITEMENABLED,0,0,0,0,0,0};
struct Menu Menus[10];
char *MenuCommand[MAXMENUS][MAXITEMS];
static void
install_menu( char *mav[], int mac )
{
struct TextAttr *ta;
struct Menu *m;
struct MenuItem *mi, **pmi;
struct IntuiText *it;
int y, i, fonthei;
char *p, *com;
if( o_nowindow || !Win )
return;
if( mac>=MAXITEMS )
mac=MAXITEMS-1;
ClearMenuStrip( Win );
Delay(3);
if( NumMenus )
Menus[NumMenus-1].NextMenu=Menus+NumMenus;
m =&Menus[NumMenus];
*m =DefaultMenu;
m->LeftEdge = NumMenus*TITWID;
m->MenuName = strcpy(salloc(strlen(mav[0])+1),mav[0]);
if( strlen(m->MenuName)>TITWID/8 )
m->MenuName[TITWID/8+1]=0;
DefaultIntuiText.ITextFont=ta=Win->WScreen->Font;
DefaultMenuItem.Height=2+(fonthei=ta->ta_YSize);
y=0;
pmi=&m->FirstItem;
for( i=1; i<mac; i++) {
it =(void *)salloc(sizeof(struct IntuiText));
*it=DefaultIntuiText;
mi =(void *)salloc(sizeof(struct MenuItem ));
*mi=DefaultMenuItem;
com=NULL;
if( p=index(mav[i],',')) {
*p=0; com=++p;
if( p=index(com,',')) {
*p=0;
mi->Command=p[1];
mi->Flags |=COMMSEQ;
}
}
if( !com || !*com) {
com=strcpy(salloc(strlen(mav[i])+2),mav[i]);
MenuCommand[NumMenus][i-1]=com;
com+=strlen(com);
*com++=13;
*com=0;
} else {
MenuCommand[NumMenus][i-1]=strcpy(salloc(strlen(com)+1),com);
}
it->IText=(UBYTE *)strcpy(salloc(strlen(mav[i])+2),mav[i]);
*pmi= mi;
pmi = &mi->NextItem;
mi->TopEdge = y;
mi->ItemFill= (APTR)it;
y+=DefaultMenuItem.Height;
}
NumMenus++;
MError:
return;
}
void
remove_menu()
{
if( NumMenus>0 ) {
struct MenuItem *mi, *nextmi;
int i,j;
for( i=0; i<NumMenus; i++ ) {
for( mi=Menus[i].FirstItem,j=0 ; mi; mi=nextmi,j++ ) {
free( ((struct IntuiText *)mi->ItemFill)->IText );
free( ((struct IntuiText *)mi->ItemFill) );
nextmi=mi->NextItem;
free(mi);
free(MenuCommand[i][j]);
}
}
NumMenus=0;
set_menu();
}
}
void
set_menu()
{
if( o_nowindow || !Win )
return;
if( NumMenus>0 )
SetMenuStrip( Win, Menus );
else
ClearMenuStrip( Win );
Delay(3);
}
int
do_getenv( void )
{
char buf[256], *val=buf;
if( ac!=3 && ac!=2 ) {
show_usage( NULL );
return 20;
}
if( !Getenv(av[ac-1],buf,256))
val="";
if( ac==2 )
printf( "%s\n", val );
else
set_var( LEVEL_SET, av[1], val );
return 0;
}
int
do_setenv( void )
{
if( ac!=3 ) {
show_usage( NULL );
return 20;
} else
setenv( av[1], av[2] );
return 0;
}
char **
read_name( char *name, int *ac )
{
FILE *file;
char **av=NULL;
*ac=0;
if( file=name ? fopen( name, "r") : stdin ) {
av=read_file( file, ac );
if( name ) fclose( file );
} else
pError( name );
return av;
}
char **
read_file( FILE *file, int *ac )
{
int buflen=4096, lines=0, i, offs, got=0;
char *buf, *tmp, *ptr, **lineptr;
if( !(buf=ptr=DosAllocMem( buflen )))
goto error;
do {
while( ptr+400 < buf+buflen && (got=myfgets(ptr, file)) && !dobreak())
ptr+=strlen(ptr)+1, lines++;
if( ptr+256 < buf+buflen ) {
offs=ptr-buf;
if( !(tmp=DosAllocMem( buflen*2 )))
goto error;
memcpy( tmp, buf, buflen );
DosFreeMem( buf );
buflen*=2, buf=tmp;
ptr=buf+offs;
}
} while( got && !dobreak());
if( !(lineptr=(char **)DosAllocMem( (lines+1)*sizeof( char * ))))
goto error;
*lineptr++=buf;
for( ptr=buf, i=0; i<lines; i++ ) {
lineptr[i]=ptr;
ptr+=strlen(ptr)+1;
}
*ac=lines;
return lineptr;
error:
if( buf ) DosFreeMem( buf );
fprintf( stderr, "Out of memory\n" );
*ac=0;
return NULL;
}
void
free_file( ptr )
char **ptr;
{
if( ptr-- ) {
if( *ptr )
DosFreeMem( *ptr );
DosFreeMem(ptr);
}
}
do_qsort( void )
{
char **lineptr;
int lines, i;
if( ac==1 ) {
lineptr=read_file( stdin, &lines);
DirQuickSort( lineptr, lines, cmp, options&1, 0 );
prepscroll(0);
for( i=0; i<lines && !dobreak(); i++ ) {
quickscroll();
puts( lineptr[i] );
}
free_file( lineptr );
} else
ierror( NULL,506 );
return 0;
}
extern int w_width;
do_truncate( void )
{
char buf[256];
int w=newwidth(), c;
char *ptr;
if( ac==2 )
w=atoi( av[1] );
prepscroll(0);
while( myfgets(buf,stdin) && !dobreak() ) {
for( c=0, ptr=buf; *ptr && c<w; ptr++ )
if( *ptr=='\t' )
c+=8-(c&7);
else if( *ptr==27 ) {
while( *ptr<'@' )
ptr++;
} else
c++;
*ptr=0;
quickscroll();
puts(buf);
}
return 0;
}
int
do_readfile( void )
{
char **rav, *str=NULL, *file=NULL;
int rac;
if( ac>2 ) file=av[2];
if( rav=read_name( file, &rac ) ) {
if( str= compile_av( rav, 0, rac, 0xA0, 0 ) )
set_var( LEVEL_SET, av[1], str );
free_file( rav );
}
return str ? 0 : 20;
}
void
foreach( char **s, int (*func)(char *s) )
{
char *str;
for( ;; ) {
str=*s;
if( !(*s=index(*s,0xA0)))
break;
**s=0;
(*func)(str);
*(*s)++=0xA0;
if( breakcheck())
return;
}
(*func)(str);
}
int
do_writefile( void )
{
char *ptr;
if( !(ptr=get_var(LEVEL_SET,av[1])))
{ fprintf(stderr,"Undefined variable %s\n",av[1]); return 20; }
foreach( &ptr, puts );
return 0;
}
int
do_split( void )
{
int i;
char *val, *gap, *oldval;
if( !(val=get_var( LEVEL_SET, av[1] )))
{ fprintf( stderr, "undefined variable %s\n", av[1] ); return 20; }
oldval=val=strcpy(salloc(strlen(val)+1),val);
for( i=2; i<ac-1; i++ ) {
if( gap=index(val,0xA0 )) *gap=0;
set_var( LEVEL_SET, av[i], val );
val="";
if( gap ) *gap=0xA0, val=gap+1;
}
set_var( LEVEL_SET, av[ac-1], val );
free(oldval);
return 0;
}
char *
copyof( char *str )
{
return strcpy(salloc(strlen(str)+1),str);
}
int
do_class( char *avline )
{
CLASS *new;
if( options&1 ) {
avline=next_word(avline);
for( new=CRoot,CRoot=NULL; new; new=new->next )
Free(new);
}
if( ac==1 ) {
for( new=CRoot; new; new=new->next )
printf("%s\n",new->name);
return 0;
}
avline=next_word(avline);
if(!(new=malloc( strlen(avline)+5)))
ierror( NULL, 512 );
else {
new->next=NULL;
strcpy( new->name,avline );
if( CRoot )
LastCRoot->next=new;
else
CRoot=new;
LastCRoot=new;
}
return 0;
}
do_getcl( void )
{
char *s=getclass(av[1]);
if( s ) printf("%s\n",s);
return 0;
}
do_action( char *argline )
{
char *args, err;
int abort=options&1;
args=compile_av( av,3,ac,' ',0 );
err=doaction(av[2],av[1],args);
if( !abort )
if( err==9 ) ierror(av[2], 205 );
else if(err==10) fprintf(stderr,"Can't identify %s\n", av[2] );
else if(err==11) fprintf(stderr,"Can't '%s' this file\n",av[1] );
else if(err==12) fprintf(stderr,"Error executing the program to '%s' this file\n",av[1] );
free(args);
return abort ? !err : err;
}
#if 0
static void
viewfile( FILE *fi )
{
char buf[256];
long pages[64];
xxxyyy
}
do_more( void )
{
FILE *fi;
int i;
if( ac==1 && !IsInteractive(Input()))
viewfile(stdin);
else
for( i=1; i<ac && !breackcheck(); i++ ) {
if( fi=fopen( av[i], "r" ))
viewfile( fi ), fclose( fi );
else
fprintf( stderr, "Can't open %s\n" );
}
#endif